from django.db import models
from fuguang.utils.models import BaseModel
from stdimage import StdImageField
from django.utils.safestring import mark_safe
# 不支持上传文件
from ckeditor.fields import RichTextField
# 支持上传文件
from ckeditor_uploader.fields import RichTextUploadingField
import datetime
import json


class CourseDirectionModel(BaseModel):
    name = models.CharField(max_length=200, unique=True, verbose_name='方向名称')
    remark = models.TextField(default="", blank=True, null=True, verbose_name="方向信息描述")
    recomment_home_hot = models.BooleanField(default=False, verbose_name='是否推荐首页最热栏目')
    recomment_home_top = models.BooleanField(default=False, verbose_name='是否推荐首页必学栏目')

    class Meta:
        db_table = "fg_course_direction"
        verbose_name_plural = "方向"
# 字段：
#     id
#     方向名称
#     方向描述
#     是否推荐到首页最热栏目
#     是否推荐到首页必学栏目

# 方向表、分类表、课程表、章节、课时 、老师表


class CourseCategoryModel(BaseModel):
    name = models.CharField(max_length=200, unique=True, verbose_name='分类名称')
    remark = models.TextField(default="", blank=True, null=True, verbose_name="分类信息描述")
    direction = models.ForeignKey(to=CourseDirectionModel, related_name="category_list", null=True, blank=True, on_delete=models.DO_NOTHING, verbose_name='方向')

    class Meta:
        db_table = "fg_course_category"
        verbose_name_plural = "课程分类"


# 老师模型类
class TeacherModel(BaseModel):
    ROLE_CHOICES = {
        (0, '讲师'),
        (1, '导师'),
        (2, '班主任'),
    }
    role = models.SmallIntegerField(choices=ROLE_CHOICES, default=0, verbose_name='讲师身份')
    title = models.CharField(max_length=100, verbose_name='职位、职称')
    signature = models.CharField(max_length=255, blank=True, null=True, verbose_name='讲师签名')
    avatar = StdImageField(upload_to='teacher/', null=True, verbose_name='头像',
                           variations={
                               # 'large': (600, 400),
                               'thumb_800x800': {'width': 800, 'height': 800},
                               # 'medium': (300, 200),
                               'thumb_400x400': {'width': 400, 'height': 400},
                               # 'thumbnail': (100, 100, True),
                               'thumb_50x50': {'width': 50, 'height': 50},
                           }
                           )
    # brief = models.TextField(max_length=500, verbose_name='个人描述')
    brief = RichTextUploadingField(max_length=500, verbose_name='个人描述')

    class Meta:
        db_table = 'fg_teacher'
        verbose_name_plural = '讲师信息'

    def __str__(self):
        return self.name

    # 返回一个图片image标签， 给管理站点返回；站点无法加载图片，返回一个image给站点
    def avatar_small(self):
        # 小图展示
        return mark_safe(f'<img style="border-radius:100%" alt="" src="{self.avatar.thumb_50x50.url}"></img>')

    avatar_small.short_description = '老师头像'
    # 图片是否显示
    avatar_small.allow_tags = True
    # 设置排序顺序
    avatar_small.admin_order_field = "avatar"


# 课程模型类
class CourseModel(BaseModel):
    COURSE_TYPE_CHOICES = {
        (0, '付费购买'),
        (1, '会员'),
        (2, '学位课程'),
    }
    LEVEL_CHOICES = {
        (0, '初级'),
        (1, '中级'),
        (2, '高级'),
    }
    STATUS_CHOICES = {
        (0, '上线'),
        (1, '下线'),
        (2, '预上线'),
    }
    course_cover = StdImageField(upload_to='course/cover/', blank=True, null=True, verbose_name='视频封面',
                                 variations={
                                     # 'large': (600, 400),
                                     'thumb_800x800': {'width': 800, 'height': 800},
                                     # 'medium': (300, 200),
                                     'thumb_400x400': {'width': 400, 'height': 400},
                                     # 'thumbnail': (100, 100, True),
                                     'thumb_108x61': {'width': 108, 'height': 61},
                                 }
                                 )
    course_video = models.FileField(upload_to="course/video/", blank=True, null=True, verbose_name='封面视频')
    course_type = models.SmallIntegerField(choices=COURSE_TYPE_CHOICES, default=0, verbose_name='付费课程')
    level = models.SmallIntegerField(choices=LEVEL_CHOICES, default=0, verbose_name='难度等级')
    # 课程状态
    status = models.SmallIntegerField(choices=STATUS_CHOICES, default=0, verbose_name='课程状态')
    # 课程描述、介绍
    description = models.TextField(null=True, blank=True, verbose_name='详情介绍')
    pub_date = models.DateField(auto_now=True, verbose_name='发布日期')
    # 学习周期
    period = models.IntegerField(default=7, verbose_name='建议学习周期（天）')
    # 课件地址
    attachment_path = models.FileField(upload_to="course/md/", blank=True, null=True, verbose_name='课件文件')
    # 课件链接
    attachment_link = models.CharField(max_length=300, blank=True, null=True, verbose_name='课件路径')
    # 课程详情：学习人数、总课时量、已经更新的课时数量     课程价格
    students = models.IntegerField(default=0, verbose_name='学习人数')
    lessons = models.IntegerField(default=0, verbose_name='总课时数量')
    pub_lessons = models.IntegerField(default=0, verbose_name='已更新的课时数量')
    price = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='课程价格')
    # 积分兑换
    credit = models.IntegerField(default=0, null=True, blank=True, verbose_name='积分兑换')
    # 是否推荐到首页：必学课程
    # 是否推荐到首页：最热课程
    recomment_home_hot = models.BooleanField(default=False, verbose_name='是否推荐首页最热栏目')
    recomment_home_top = models.BooleanField(default=False, verbose_name='是否推荐首页必学栏目')
    # 方向、分类、老师
    direction = models.ForeignKey(to=CourseDirectionModel, related_name='course_list', on_delete=models.DO_NOTHING, null=True, blank=True, db_constraint=False, verbose_name='方向')
    category = models.ForeignKey(to=CourseCategoryModel, related_name='course_list', on_delete=models.DO_NOTHING, null=True, blank=True, db_constraint=False, verbose_name='分类')
    # 老师
    teacher = models.ForeignKey(to=TeacherModel, related_name='course_list', on_delete=models.DO_NOTHING, null=True, blank=True, db_constraint=False, verbose_name='老师')

    class Meta:
        db_table = 'fg_course_info'
        verbose_name_plural = '课程信息表'

    def __str__(self):
        return self.name

    # 返回一个图片image标签， 给管理站点返回；站点无法加载图片，返回一个image给站点
    def course_cover_small(self):
        # 小图展示
        return mark_safe(f'<img style="border-radius:100%" alt="" src="{ self.course_cover.thumb_108x61.url }"></img>')

    # 图片的描述
    course_cover_small.short_description = '视频封面'
    # 图片是否显示
    course_cover_small.allow_tags = True
    # 设置排序顺序
    course_cover_small.admin_order_field = "course_cover"

    # 属性
    @property
    def discount(self):
        # 拼接折扣信息，返回
        # 课程的优惠信息
        # 查询，是否参与活动，如果参与，判断是否过期，如果未过期，获取折扣信息，参与当前课程价格计算
        # 获取当前时间，用于比较活动是否过期
        now_time = datetime.datetime.now()
        last_activate = self.price_list.filter(activate__start_time__lt=now_time, activate__end_time__gt=now_time).order_by('-id').first()
        # 拼接数据
        # 计算数据
        # 给前端返回的是具体的折扣信息
        # 优惠类型
        type_text = "优惠类型"
        # 过期时间
        expire = -1
        # 优惠后的价格
        price = 20

        # if not last_activate:
        #     print('当前课程没有优惠')
        #     price = self.price

        if last_activate:
            # 有活动，获取当前课程所对应的优惠信息
            print(last_activate.activate.name)
            print(last_activate.activate.end_time)
            # 折扣类型
            print(last_activate.discount.discount_type.name)
            type_text = last_activate.discount.discount_type.name
            # 过期时间   将时间转换成时间戳进行计算
            expire = last_activate.activate.end_time.timestamp() - now_time.timestamp()
            # 价格计算，获取当前课程原价
            course_price = float(self.price)
            # 考虑：限制条件   优惠条件，原价是否满足限制条件
            condition_price = last_activate.discount.condition
            # 判断当前价格是否满足限制条件
            if course_price >= condition_price:
                # 计算当前课程参与的优惠了，以及优惠后的价格
                sale = last_activate.discount.sale
                # 判断sale属于哪种类型
                if sale == "0":
                    # 免费
                    price = 0
                elif sale[0] == "*":
                    # 折扣
                    price = course_price * float(sale[1:])
                    # * x0.8
                    # - 100 -80
                elif sale[0] == "-":
                    # 满减
                    price = course_price - float(sale[1:])
                price = float(f'{price:.2f}')
        else:
            print('当前课程没有参与活动')
            price = self.price

        return {
            'type': type_text,
            'expire': expire,
            'price': price,
        }

    def discount_json(self):
        # 必须转成字符串才能保存到es中。所以该方法提供给es使用的。
        return self.discount


# 课程章节
class CourseChapterModel(BaseModel):
    orders = models.SmallIntegerField(default=1, verbose_name='第几章')
    summary = RichTextField(blank=True, null=True, verbose_name='章节描述')
    pub_date = models.DateField(auto_now_add=True, verbose_name='章节发布时间')
    course = models.ForeignKey(to=CourseModel, on_delete=models.CASCADE, db_constraint=False, verbose_name='课程')

    def get_lesson_list(self):
        result_list = []
        lesson_list = self.lesson_list.filter(is_deleted=False, is_show=True).order_by('orders')
        for ls in lesson_list:
            result_list.append(
                {
                    'id': ls.id,
                    'name': ls.name,
                    'orders': ls.orders,
                    'duration': ls.duration,
                    'pub_date': ls.pub_date,
                    'lesson_link': ls.lesson_link,
                    'free_trail': ls.free_trail
                }
            )
        return result_list

    class Meta:
        db_table = "fg_course_chapter"
        verbose_name_plural = "课程章节"

    def __str__(self):
        return "第 %d 章 - %s" % (self.orders, self.name)


# 课时--小节
class CourselessonModel(BaseModel):
    LESSON_CHOICES = {
        (0, '文档'),
        (1, '练习'),
        (2, '视频'),
    }
    orders = models.SmallIntegerField(default=1, verbose_name="第几节")
    lesson_type = models.SmallIntegerField(choices=LESSON_CHOICES, default=2, verbose_name='课时类型')
    duration = models.CharField(max_length=100, blank=True, null=True, verbose_name="课时时长")
    lesson_link = models.CharField(max_length=255, verbose_name='课时链接')
    pub_date = models.DateTimeField(auto_now_add=True, verbose_name="课时发布时间")
    # 是否可以免费观看
    free_trail = models.BooleanField(default=False, verbose_name="是否可以免费观看")
    chapter = models.ForeignKey(to=CourseChapterModel, related_name="lesson_list", db_constraint=False, on_delete=models.CASCADE, verbose_name="章节")
    course = models.ForeignKey(to=CourseModel, related_name="lesson_list", db_constraint=False, on_delete=models.CASCADE, verbose_name='课程')

    class Meta:
        db_table = "fg_course_lesson"
        verbose_name_plural = "课时"

    def __str__(self):
        return "第 %d 章 - 第 %d 课时  -  %s" % (self.chapter.orders, self.orders, self.name)


# 活动模型
class ActivateModel(BaseModel):
    start_time = models.DateTimeField(default=datetime.datetime.now(), verbose_name='开始时间')
    end_time = models.DateTimeField(default=datetime.datetime.now(), verbose_name='结束时间')
    # 活动介绍
    description = RichTextUploadingField(blank=True, null=True, verbose_name='活动介绍')
    remark = models.CharField(max_length=300, blank=True, null=True, verbose_name='备注信息')

    class Meta:
        db_table = 'fg_activate'
        verbose_name_plural = '优惠活动'


# 折扣类型 优惠类型
class DiscountTypeModel(BaseModel):
    remark = models.CharField(max_length=300, blank=True, null=True, verbose_name='备注信息')

    class Meta:
        db_table = 'fg_discount_type'
        verbose_name_plural = '优惠类型'


# 折扣表、优惠公式表
class DiscountModel(BaseModel):
    discount_type = models.ForeignKey(to=DiscountTypeModel, on_delete=models.CASCADE, db_constraint=False, verbose_name='折扣类型')
    # 优惠限制条件
    # 不填写的情况，表示优惠没有门槛
    condition = models.IntegerField(blank=True, default=0, verbose_name='优惠条件')
    # 定义折扣
    sale = models.CharField(max_length=50, verbose_name='优惠公式', help_text='-表示满减，示例：-10<br/> *表示打折，示例：*0.8<br/> 0表示免费送')
    # 0 表示免费
    # -10 表示满减
    # *0.8 表示折扣
    # sale = '-100'

    class Meta:
        db_table = 'fg_discount'
        verbose_name_plural = '折扣表'


# 课程价格表  课程活动表
class CourseActivateModel(BaseModel):
    activate = models.ForeignKey(to=ActivateModel, on_delete=models.CASCADE, related_name='price_list', db_constraint=False, verbose_name='优惠活动')
    course = models.ForeignKey(to=CourseModel, on_delete=models.CASCADE, related_name='price_list', db_constraint=False, verbose_name='课程')
    discount = models.ForeignKey(to=DiscountModel, on_delete=models.CASCADE, related_name='price_list', db_constraint=False, verbose_name='折扣')

    class Meta:
        db_table = 'fg_course_activate_price'
        verbose_name_plural = '课程活动价格表'

    def __str__(self):
        return "课程：%s - 活动：%s - 折扣：%s" % (self.course.name, self.activate.name, self.discount.sale)
